package cn.yuanqiao.es.service.impl;

import cn.yuanqiao.common.constant.CacheConstants;
import cn.yuanqiao.common.constant.Constants;
import cn.yuanqiao.common.constant.HttpStatus;
import cn.yuanqiao.common.core.domain.AjaxResult;
import cn.yuanqiao.common.core.domain.entity.SysRole;
import cn.yuanqiao.common.core.text.Convert;
import cn.yuanqiao.common.domain.DataScopeStaticValue;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.service.RedisService;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.common.core.page.TableDataInfo;
import cn.yuanqiao.es.domain.ElasticsearchQuery;
import cn.yuanqiao.es.domain.QueryFile;
import cn.yuanqiao.es.domain.QueryParameter;
import cn.yuanqiao.es.mapper.ElasticsearchApiMapper;
import cn.yuanqiao.es.service.ElasticsearchApiService;
import cn.yuanqiao.es.service.ElasticsearchIndex;
import cn.yuanqiao.es.service.ElasticsearchTemplate;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggest;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggestOption;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.tika.Tika;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @ProjectName: ruoyi-modules-system
 * @Package: cn.yuanqiao.es.service
 * @ClassName: ElasticsearchApiServiceImpl
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2023/6/20 17:06
 * @Version: 1.0
 */
@Service
public class ElasticsearchApiServiceImpl implements ElasticsearchApiService {
    private static final Logger log = LoggerFactory.getLogger(ElasticsearchApiServiceImpl.class);
    @Autowired
    ElasticsearchApiMapper elasticsearchApiMapper;

    @Autowired
    ElasticsearchIndex elasticsearchIndex;

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    @Autowired
    private RedisService redisService;

    /**
     * 用于标记当前索引库是否正在操作，如果正在创建，则其他请求不再处理
     */
    private boolean isUsing = false;

    @Override
    public void tess(List<Map<String, Object>> list) {
        List<String> aa = new ArrayList<>();
        aa.add("e8f8b51ed7164483949a06cecc71547c");
        elasticsearchIndex.dropDoc(aa, "test");
    }


    /**
     * 创建和重建索引实现
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/17 17:56
     */
    @Override
    public AjaxResult createIndex(List<Map<String, Object>> mapList) {
        boolean create = false;
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        int totalNums = 0;
        //判断是否传了ids  有则删除数据 无则删除整个索引 然后重新创建索引
        if (null != mapList && !mapList.isEmpty()) {
            //提取组件id 进行索引删除
            List<String> fileTableNames = mapList.stream().map(c -> c.get("fileTableName").toString()).collect(Collectors.toList());
            if (mapList.get(0).containsKey("id")) {
                List<String> ids = mapList.stream().map(c -> c.get("id").toString()).collect(Collectors.toList());
                elasticsearchIndex.dropDoc(ids, tenantCode);
                totalNums = copeTenantCategoryDataIds(tenantCode, mapList);
            } else if (ObjectUtils.isNotEmpty(fileTableNames)) {
                //删除索引
                elasticsearchIndex.dropIndex(tenantCode);
                create = elasticsearchIndex.createIndex(tenantCode);
                if (!create) {
                    return AjaxResult.error("创建索引失败");
                }
                totalNums = copeTenantDA(tenantCode, null, fileTableNames);
            }
        }
        return AjaxResult.success("创建索引成功", totalNums);
    }

    /**
     * 全量索引和重建索引功能
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/17 18:38
     */
    @Override
    public AjaxResult completeIndex(List<String> fileTableName) {
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        //先删除索引
        elasticsearchIndex.dropIndex(tenantCode);
        boolean create = elasticsearchIndex.createIndex(tenantCode);
        if (!create) {
            return AjaxResult.error("创建索引失败,新建索引未成功");
        }
        if (ObjectUtils.isNotEmpty(fileTableName)) {
            copeTenantDA(tenantCode, null, fileTableName);
        }
        log.info("全量创建索引完成 !");
        return AjaxResult.success("创建索引成功");
    }

    /**
     * 全量索引和重建索引功能  定时任务
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/17 18:38
     */
    @Override
    public AjaxResult completeIndexJob(String tenantCode) {
        //先删除索引
        elasticsearchIndex.dropIndex(tenantCode);
        boolean create = elasticsearchIndex.createIndex(tenantCode);
        if (!create) {
            return AjaxResult.error("创建索引失败,新建索引未成功");
        }
        copeTenantDA(tenantCode, null, null);
        return AjaxResult.success("创建索引成功");
    }


    /**
     * 删除索引功能实现
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/17 18:34
     */
    @Override
    public AjaxResult dropIndex(List<String> ids) {
        boolean drop = false;
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        //判断是否传了ids  有则删除数据 无则删除整个索引
        if (null == ids && ids.isEmpty()) {
            drop = elasticsearchIndex.dropIndex(tenantCode);
            elasticsearchApiMapper.updateIndex1(tenantCode + Constants.BIG_TABLE_YQDA, "");
        } else {
            drop = elasticsearchIndex.dropDoc(ids, tenantCode);
            if (ids != null) {
                String idsStr = ids.toString();
                if (idsStr.startsWith("[")) idsStr = idsStr.substring(1);
                if (idsStr.endsWith("]")) idsStr = idsStr.substring(0, idsStr.length() - 1);
                elasticsearchApiMapper.updateIndex1(tenantCode + Constants.BIG_TABLE_YQDA, " where DA_ID in (" + idsStr + ") ");
            }
        }
        if (!drop) {
            return AjaxResult.error("删除索引失败");
        }
        return AjaxResult.success("删除索引成功");
    }

    /**
     * 增量索引功能实现
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/25 19:58
     */
    public AjaxResult cincrementIndex(List<String> fileTableNames) {
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        if (ObjectUtils.isNotEmpty(fileTableNames)) {
            copeTenantDA(tenantCode, "3", fileTableNames);
        }
        log.info("增量创建索引完成 !");
        return AjaxResult.success("创建索引成功");
    }

    /**
     * 增量索引 定时任务
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/11/27 10:57
     */
    public AjaxResult cincrementIndexJob(String tenantCode) {
        List<String> fileTableNames = new ArrayList<>();
        copeTenantDA(tenantCode, "3", fileTableNames);
        return AjaxResult.success("创建索引成功");
    }

    /**
     * 索引查询功能实现
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/19 18:52
     */
    @Override
    public TableDataInfo search(QueryFile queryFile) {
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        //判断索引是否存在
        boolean exists = elasticsearchIndex.existsIndex(tenantCode.toLowerCase());
        if (!exists) {
            throw new ServiceException("请先创建索引!");
        }
        List<Map<String, Object>> result = new ArrayList<>();
        TableDataInfo rspData = new TableDataInfo();
//        //查询排序
//        if (StringUtils.isBlank(queryFile.getOrder())) {
//            String ordering = elasticsearchApiMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
//                    "type= '0' and menu_id= '" + queryFile.getMenuId() + "' ");
//            if (StringUtils.isNotBlank(ordering)) {
//                queryFile.setOrder(ordering.replaceAll("$", " "));
//            }
//        }
        SearchResponse<Object> searchResponse = elasticsearchTemplate.search(queryFile, tenantCode);
        if (searchResponse == null) {
            rspData.setRows(result);
            return rspData;
        }
        List<Object> hitList = searchResponse.hits().hits().stream().map(m -> m.source()).collect(Collectors.toList());
//        List<Hit<Object>> hits = searchResponse.hits().hits();
//        if (hits != null && hits.size() > 0) {
//            for (Hit a : hits) {
//                Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(a.source()), new TypeReference<Map<String, Object>>() {
//                });
//                Map<String, Object> map1 = JSONObject.parseObject(JSONObject.toJSONString(a.highlight()), new TypeReference<Map<String, Object>>() {
//                });
//                Iterator<Map.Entry<String, Object>> iterator = map1.entrySet().iterator();
//                while (iterator.hasNext()) {
//                    Map.Entry<String, Object> next = iterator.next();
//                    if (map.containsKey(next.getKey())) {
//                        map.put(next.getKey(),next.getValue().);
//                    }
//                }
//                result.add(map);
//            }
//            rspData.setRows(authority(result, queryFile.getMenuId()));
//        } else {
//            rspData.setRows(result);
//        }
        if (hitList != null && hitList.size() > 0) {
            for (Object a : hitList) {
                Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(a), new TypeReference<Map<String, Object>>() {
                });
                result.add(map);
            }
            rspData.setRows(authority(result, queryFile.getMenuId()));
        } else {
            rspData.setRows(result);
        }
        long value = searchResponse.hits().total().value();
        if (value > 1000000) {
            value = 1000000;
        }
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setTotal(Integer.parseInt(String.valueOf(value)));
        return rspData;
    }

    /**
     * 查询联想词
     *
     * @param key
     * @return
     */
    @Override
    public List<String> searchAssociate(String key) {
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        //判断索引是否存在
        boolean exists = elasticsearchIndex.existsIndex(tenantCode.toLowerCase());
        if (!exists) {
            throw new ServiceException("请先创建索引!");
        }
        List<String> result = new ArrayList<>();
        SearchResponse<Object> searchResponse = elasticsearchTemplate.searchAssociate(key, tenantCode);
        if (searchResponse == null) {
            return result;
        }
        List<Object> hitList = Arrays.asList(searchResponse.suggest().get("my-suggest").toArray());
        if (hitList != null && hitList.size() > 0) {
            for (Object suggest : hitList) {
                Suggestion suggest1 = (Suggestion) suggest;
                if (suggest1.isCompletion()) {
                    CompletionSuggest completionSuggester = suggest1.completion();
                    List<CompletionSuggestOption> options = completionSuggester.options();
                    for (CompletionSuggestOption op : options) {
                        result.add(op.text());
                    }
                }
            }
        }
        return result;
    }

    /**
     * 查询公共库功能实现
     *
     * @param
     * @return cn.yuanqiao.common.core.domain.AjaxResult
     * @author hbWang
     * @date 2023/6/19 18:52
     */
    @Override
    public TableDataInfo searchCommunal(QueryFile queryFile, String state, String ztId) {
        String tenantCode = SecurityUtils.getTenantCode();
        List<String> list = new ArrayList<>();
        StringBuilder sql = new StringBuilder();
        //     if (StringUtils.isNotBlank(queryFile.getCategoryId())) {
        //     String categoryIds = queryFile.getCategoryId().replaceAll(",", "','");
        if (state.equals("2")) {
            sql.append(" select  gk.DA_ID from ").append(tenantCode).append("_YQ_DA_GEREN_KU gk").append(" LEFT JOIN ")
                    .append(tenantCode + Constants.TABLE_YQ_ZHUANTI_GEREN_DATA).append(" ztgk ON ztgk.GEREN_ID =gk.ID   where ztgk.ZHUANTI_ID = '")
                    .append(ztId).append("' and ztgk.STATE = '5' ");
            list = elasticsearchApiMapper.selectAppDataListLeft(sql.toString(), " DA_ID ", " 1=1 ");
        } else {
            // sql.append(" CATEGORY_ID in ('").append(categoryIds).append("') ");
            sql.append(" TYPE_STATE = '").append(state).append("' ");
            if (state.equals("1")) {
                sql.append(" and CREATOR_ID = '").append(SecurityUtils.getUserId()).append("' ");
            }
            list = elasticsearchApiMapper.selectAppDataList(tenantCode + "_YQ_DA_GEREN_KU", " DA_ID ", sql.toString());
        }
        //   }
        TableDataInfo tableDataInfo = new TableDataInfo();
        if (list != null && list.size() > 0) {
            QueryParameter queryParams = new QueryParameter();
            queryParams.setShowType("7");
            queryParams.setQueryType("7");
            queryParams.setColumn("ID");
            queryParams.setValue(list.stream().collect(Collectors.joining(",")));
            if (queryFile.getQueryParameters() == null || queryFile.getQueryParameters().size() < 0) {
                List<QueryParameter> queryParameters = new ArrayList<>();
                queryParameters.add(queryParams);
                queryFile.setQueryParameters(queryParameters);
            } else {
                queryFile.getQueryParameters().add(queryParams);
            }
            tableDataInfo = search(queryFile);
        }
        return tableDataInfo;
    }

    /**
     * 判断电子文件存在哪些字段
     *
     * @param query
     * @return
     */
    @Override
    public String queryMultiMatch(ElasticsearchQuery query) {
        //获取当前租户信息SecurityUtils.getTenantCode()
        String tenantCode = SecurityUtils.getTenantCode();
        query.setIdexName(tenantCode);
        return elasticsearchTemplate.queryMultiMatch(query);
    }

    /**
     * 根据id重建和创建索引
     *
     * @param
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/6/26 16:14
     */
    private int copeTenantCategoryDataIds(String tenantCode, List<Map<String, Object>> mapList) {
        //查询配置参数
        String uplodPath = selectConfigByKey("YQ_MNT");
        List<String> fileTableName = mapList.stream().map(c -> c.get("fileTableName").toString()).distinct().collect(Collectors.toList());
        List<Map<String, Object>> tenantCategoryTableList = elasticsearchApiMapper.selectCategoryTableData(
                tenantCode + Constants.BIG_TABLE_NAME, fileTableName);

        for (Map<String, Object> tenantCategory : tenantCategoryTableList) {
            String categoryName = tenantCategory.get("FILE_TABLE_NAME").toString();
            String groupId = tenantCategory.get("GROUP_ID").toString();
            String ids = mapList.stream().filter(f -> f.get("fileTableName").equals(categoryName)).map(m -> m.get("id").toString()).collect(Collectors.joining(","));
            String fileds = mdataList(groupId, "0", null, tenantCode);
            threadDA(fileds, categoryName, uplodPath, tenantCode, tenantCategoryTableList, ids, null);
        }
        return 1;
    }

    /**
     * 处理索引信息
     *
     * @param tenantCode 索引名字
     * @param isIndex    是否建立索引
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/6/25 18:53
     */
    private int copeTenantCategoryData(String tenantCode, String isIndex, List<String> fileTableName) {
//        if (isUsing) {
//            throw new ServiceException("资源占用中，请等待。");
//        }
        isUsing = true;
        List<Map<String, Object>> tenantCategoryTableList = elasticsearchApiMapper.selectCategoryTableData(
                tenantCode + Constants.BIG_TABLE_NAME, fileTableName);
        //查询配置参数
        String uplodPath = selectConfigByKey("YQ_MNT");
        //todo 多线程处理数据
        // 定义线程池
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        Integer success = threadFileList(executorService, tenantCategoryTableList, isIndex, uplodPath, tenantCode);
        // isUsing = false;
        return success;
    }


    public Integer threadFileList(Executor executorService, List<Map<String, Object>> tenantCategoryTableList, String isIndex, String uplodPath, String tenantCode) {
        Integer userNum = tenantCategoryTableList.size();
        List<Integer> pageNumList = new ArrayList<>();
        for (int i = 0; i < userNum; i++) {
            pageNumList.add(i);

        }
        List<Map<String, Object>> sourceList = elasticsearchApiMapper.selectMDataListTableData
                (tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                        " and tn.TYPE = 0 ");
        List<String> fileds = sourceList.stream().map(m -> m.get("FIELD_NAME").toString()).distinct().collect(Collectors.toList());
        if (ObjectUtils.isNotEmpty(fileds)) {
            fileds.add("CREATE_ID");
            fileds.add("IS_ENTITY");
            fileds.add("GDCS_ID");
            fileds.add("EFILE_COUNT");
        }
        // 定义线程安全的分页数据，用作多线程处理
        List<Integer> syncPageNumList = Collections.synchronizedList(pageNumList);
        List<CompletableFuture<Integer>> completableFutureList = new ArrayList<>();
        syncPageNumList.stream().forEach(pageNumber -> {
            // 多线程
            completableFutureList.add(CompletableFuture.supplyAsync(() -> {
                Map<String, Object> tenantCategoryS = tenantCategoryTableList.get(pageNumber);
                //查询组件信息
                int successNum = fileList(tenantCategoryS, null, isIndex, uplodPath, fileds, tenantCode);
                return successNum;
            }, executorService));
        });
        // 获取多线程处理成功数据量
        Integer success = 0;
        for (CompletableFuture<Integer> completableFuture : completableFutureList) {
            try {
                success += completableFuture.join();
            } catch (Exception e) {
                log.error("创建索引异常---------->" + e.getMessage());
            }
        }
        return success;
    }


    /**
     * 处理组件信息
     *
     * @param
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/6/25 14:34
     */
    private int fileList(Map<String, Object> tenantCategory, String ids,
                         String isIndex, String uplodPath, List<String> fileds, String tenantCode) {
        String groupId = tenantCategory.get("GROUP_ID").toString();
        //组件的表名
        String fileTable = tenantCategory.get("FILE_TABLE_NAME").toString();
        String file = mdataList(groupId, "0", fileds, tenantCode);
        StringBuilder sql = new StringBuilder("");
        if (StringUtils.isNotBlank(ids)) {
            sql.append(" AND f.ID in ( ").append(ids).append(")");
        }
        if (StringUtils.isNotBlank(isIndex)) {
            sql.append(" AND f.IS_INDEX = ").append(isIndex);
        }
        // 一次加载全部数据，可能导致内存溢出，分批加载
        int start = 0;// 从开始读取数据
        int step = 1000;// 步长，每次读取数据量
        // 本次操作创建记录数
        int totalNums = 0;
        String filterSql = sql.toString() + " ORDER BY f.ID ";
        while (!"".equals(filterSql.trim())) {
            StringBuilder sqlff = new StringBuilder(filterSql);
            sqlff.append(" LIMIT " + step + " OFFSET " + start);
            List<Map<String, Object>> fileListData = elasticsearchApiMapper.selectFileTableData(fileTable, " f.ID " + file, sqlff.toString());

            if (fileListData != null && fileListData.size() > 0) {
                if (fileListData.size() < step) {//如果比步长值小，说明已经是当前迭代门类的最后一批数据了，处理完数据后要跳出内层循环
                    /*
                     * 重要！！！ 每次迭代重置filterSql值
                     */
                    filterSql = "";
                }
                //拼接文件信息
                List<Map<String, Object>> efileListData = efileList(fileListData, tenantCategory, uplodPath, tenantCode);
                if ("0".equals(isIndex)) {
                    List<String> fids = fileListData.stream().map(m -> String.valueOf(m.get("ID"))).collect(Collectors.toList());
                    elasticsearchIndex.dropDoc(fids, tenantCode);
                }
                String idsData = fileListData.stream().map(f -> String.valueOf(f.get("ID"))).collect(Collectors.joining(","));
                elasticsearchIndex.insertDocList(efileListData, tenantCode);
                elasticsearchApiMapper.updateIndex(fileTable, " ID in (" + idsData + ") ");
                elasticsearchApiMapper.updateIndex(tenantCode + Constants.BIG_TABLE_YQDA, " DA_ID in (" + idsData + ") ");
                totalNums += fileListData.size();
                log.debug("共" + totalNums + "条数据创建索引完毕");
                // 每次读取step条
                start += step;
            } else {
                break;
            }
        }
        return totalNums;
    }

    /**
     * 处理文件信息
     *
     * @param
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/6/25 14:55
     */
    private List<Map<String, Object>> efileList(List<Map<String, Object>> fileList, Map<String, Object> tenantCategory, String uplodPath, String tenantCode) {

        List<Map<String, Object>> efileData = new ArrayList<>();
        //电子文件件表名获取
        String efileTable = tenantCategory.get("EFILE_TABLE_NAME") == null ? "" : tenantCategory.get("EFILE_TABLE_NAME").toString();
        fileList.forEach(file -> {
            file.forEach((key, value) -> {
                file.put(key, value == null ? value : String.valueOf(value));
            });
            //判断如果没有电子件表名则不进行附件处理
            if (StringUtils.isNotBlank(efileTable)) {
                List<Map<String, Object>> efileList = elasticsearchApiMapper.selectEFileTableData(efileTable, " and CON_TABLE_ID = '" + file.get("ID") + "' ");
                if (efileList != null && efileList.size() > 0) {
                    StringBuilder pathName = new StringBuilder(" ");
                    StringBuilder pathText = new StringBuilder(" ");
                    for (int i = 0; i < efileList.size(); i++) {
                        Map<String, Object> efil = efileList.get(i);
                        if (efil.containsKey("IDENTIFICATION_PATH")) {
                            if (ObjectUtils.isNotEmpty(efil.get("IDENTIFICATION_PATH"))) {
                                String path = efil.get("DOC_MNT").toString() + efil.get("IDENTIFICATION_PATH").toString();
                                pathName.append(efil.get("DOC_NAME")).append(" / ");
                                //解析文件
                                pathText.append(analysisFile(path, file.get("ID").toString())).append(" / ");
                                continue;
                            }
                        }
                        if (StringUtils.isNotBlank(efil.get("PATH").toString())) {
                            String path = efil.get("DOC_MNT").toString() + efil.get("PATH").toString();
                            pathName.append(efil.get("DOC_NAME")).append(" / ");
                            //解析文件
                            pathText.append(analysisFile(path, file.get("ID").toString())).append(" / ");
                        }
                    }
                    file.put("pathDocName", pathName.toString());
                    file.put("pathDocText", pathText.toString());
                }
                if (file.containsKey("STATE")) {
                    switch (file.get("STATE").toString()) {
                        case "5":
                            file.put("STATE", "已归档");
                            break;
                        default:
                            file.put("STATE", "已归档");
                    }
                }
            }
            //门类编码
            file.put("categoryCode", tenantCategory.get("CODE").toString());
            //门类id
            file.put("categoryId", tenantCategory.get("ID").toString());
            //件表表名
            file.put("sub_table_name", tenantCategory.get("FILE_TABLE_NAME").toString());
            file.replaceAll((k, v) -> v == null ? "" : String.valueOf(v));
            efileData.add(file);

        });

        return efileData;
    }

    /**
     * 处理索引信息根据件总表
     *
     * @param tenantCode 索引名字
     * @param isIndex    是否建立索引
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/6/25 18:53
     */
    private int copeTenantDA(String tenantCode, String isIndex, List<String> fileTableName) {
        if (isUsing) {
            throw new ServiceException("资源占用中，请等待。");
        }
        try {
            isUsing = true;
            List<Map<String, Object>> tenantCategoryTableList = elasticsearchApiMapper.selectCategoryTableData(
                    tenantCode + Constants.BIG_TABLE_NAME, fileTableName);
            String groupId = tenantCategoryTableList.stream().map(m -> m.get("GROUP_ID").toString()).collect(Collectors.joining("','"));
            String subTableName = tenantCategoryTableList.stream().map(m -> m.get("FILE_TABLE_NAME").toString()).collect(Collectors.joining("','"));
            String file = mdataList(groupId, "0", null, tenantCode);
            //查询配置参数= selectConfigByKey("YQ_MNT");
            String uplodPath = "";
            Integer success = threadDA(file, subTableName, uplodPath, tenantCode, tenantCategoryTableList, null, isIndex);
        }catch (Exception e){

        }finally {
            isUsing = false;
        }
        return 1;
    }


    public Integer threadDA(String file, String subTableName, String uplodPath, String tenantCode,
                            List<Map<String, Object>> tenantCategoryTableList, String ids, String isIndex) {
        StringBuilder sql = new StringBuilder("");
        if (StringUtils.isNotBlank(ids)) {
            sql.append(" AND f.DA_ID in ( ").append(ids).append(")");
        }
        if (StringUtils.isNotBlank(isIndex)) {
            sql.append(" AND f.IS_INDEX != ").append(isIndex);
        }
        sql.append(" AND f.SUB_TABLE_NAME in ('").append(subTableName).append("') ");
        // 一次加载全部数据，可能导致内存溢出，分批加载
        int start = 0;// 从开始读取数据
        int step = 1000;// 步长，每次读取数据量
        // 本次操作创建记录数
        int totalNums = 0;
        String filterSql = sql.toString();
        while (!"".equals(filterSql.trim())) {
            StringBuilder sqlff = new StringBuilder(filterSql);
            sqlff.append(" order by DA_ID LIMIT " + step + " OFFSET " + start);
            List<Map<String, Object>> fileListData = elasticsearchApiMapper.selectFileTableData(
                    tenantCode + Constants.BIG_TABLE_YQDA, "f.DA_ID AS ID , f.SUB_TABLE_NAME " + file, sqlff.toString());
            if (fileListData != null && fileListData.size() > 0) {
                if (fileListData.size() < step) {//如果比步长值小，说明已经是当前迭代门类的最后一批数据了，处理完数据后要跳出内层循环
                    /*
                     * 重要！！！ 每次迭代重置filterSql值
                     */
                    filterSql = "";
                }
                //todo 多线程处理数据
                // 定义线程池
                log.info("创建索引:共" + fileListData.size() + "条数据;");
                ExecutorService executorService = Executors.newFixedThreadPool(5);
                List<Map<String, Object>> maps = threadFileListDa(executorService, fileListData, tenantCategoryTableList, isIndex, uplodPath, tenantCode);
//                try {
//                    elasticsearchIndex.insertDocList(maps, tenantCode);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
                // 每次读取step条
                start += step;
            } else {
                break;
            }
        }
        return 1;
    }

    public List<Map<String, Object>> threadFileListDa(Executor executorService, List<Map<String, Object>> fileListData,
                                                      List<Map<String, Object>> tenantCategoryTableList, String isIndex, String uplodPath, String tenantCode) {
        List<Map<String, Object>> efileListDataS = new ArrayList<>();
        // 计算分页数据
        Integer userNum = fileListData.size();
        int pageNumTotal = userNum / Constants.DEFAULT_PAGESIZE;
        List<Integer> pageNumList = new ArrayList<>();
        for (int i = 0; i < pageNumTotal; i++) {
            pageNumList.add(i);
        }
        if (0 == (pageNumTotal) && userNum > 0) {
            pageNumList.add(0);
        }
        // 定义线程安全的分页数据，用作多线程处理
        List<Integer> syncPageNumList = Collections.synchronizedList(pageNumList);
        List<CompletableFuture<Integer>> completableFutureList = new ArrayList<>();
        syncPageNumList.stream().forEach(pageNumber -> {
            // 多线程
            completableFutureList.add(CompletableFuture.supplyAsync(() -> {
                List<Map<String, Object>> list = new ArrayList<>();
                Integer startSy = pageNumber * Constants.DEFAULT_PAGESIZE;
                Integer endSy = (pageNumber + 1) * Constants.DEFAULT_PAGESIZE;
                if (pageNumber.equals(pageNumList.get(pageNumList.size() - 1))) {
                    endSy = fileListData.size();
                }
                list.addAll(fileListData.subList(startSy, endSy));
                List<Map<String, Object>> efileListData = efileListDA(list, tenantCategoryTableList, uplodPath, tenantCode);
                //     efileListDataS.addAll(efileListData);

                String idsData = efileListData.stream().map(f -> f.get("ID").toString()).collect(Collectors.joining(","));
                try {
                    if (StringUtils.isNotBlank(isIndex)) {
                        List<String> fids = efileListData.stream().map(m -> m.get("ID").toString()).collect(Collectors.toList());
                        elasticsearchIndex.dropDoc(fids, tenantCode);
                    }
                    boolean b = elasticsearchIndex.insertDocList(efileListData, tenantCode);
                    if (!b) {
                        log.error("创建索引失败:档案id:(" + idsData + ");第" + startSy + "至" + endSy + "条");
                    } else {
                        elasticsearchApiMapper.updateIndex(tenantCode + Constants.BIG_TABLE_YQDA, " DA_ID in (" + idsData + ") ");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return efileListData.size();
            }, executorService));
        });
        // 获取多线程处理成功数据量
        Integer success = 0;
        for (CompletableFuture<Integer> completableFuture : completableFutureList) {
            try {
                success += completableFuture.join();
            } catch (Exception e) {
            }
        }
        return efileListDataS;
    }


    /**
     * 处理文件信息 件总表
     *
     * @param fileList 件信息     tenantCategoryTableList 所有门类信息     uplodPath 上传地址
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author hbWang
     * @date 2023/11/29 11:23
     */
    private List<Map<String, Object>> efileListDA(List<Map<String, Object>> fileList,
                                                  List<Map<String, Object>> tenantCategoryTableList, String uplodPath, String tenantCode) {
        List<Map<String, Object>> efileData = new ArrayList<>();
        try {

            for (Map<String, Object> file : fileList) {
                List<Map<String, Object>> tenantCategory = tenantCategoryTableList.stream().filter(f -> f.get("FILE_TABLE_NAME").equals(file.get("SUB_TABLE_NAME")))
                        .collect(Collectors.toList());
                //电子文件件表名获取
                String efileTable = tenantCategory.get(0).get("EFILE_TABLE_NAME") == null ? "" : tenantCategory.get(0).get("EFILE_TABLE_NAME").toString();
                String fileTable = tenantCategory.get(0).get("FILE_TABLE_NAME").toString();
                if (file.containsKey("STATE")) {
                    switch (file.get("STATE").toString()) {
                        case "5":
                            file.put("STATE", "已归档");
                            break;
                        default:
                            file.put("STATE", "已归档");
                    }
                }
                //拼音检索用
                file.put("pinyin_basis_data", file.values());
                StringBuilder pathName = new StringBuilder(" ");
                StringBuilder pathText = new StringBuilder(" ");
                //判断如果没有电子件表名则不进行附件处理
                if (StringUtils.isNotBlank(efileTable)) {
                    List<Map<String, Object>> efileList = elasticsearchApiMapper.selectEFileTableData(efileTable, " and CON_TABLE_ID = '" + file.get("ID") + "' ");
                    if (efileList != null && efileList.size() > 0) {
                        for (int i = 0; i < efileList.size(); i++) {
                            Map<String, Object> efil = efileList.get(i);
                            if (StringUtils.isNotBlank(efil.get("PATH").toString())) {
                                String path = efil.get("DOC_MNT").toString() + efil.get("PATH").toString();
                                pathName.append(efil.get("DOC_NAME")).append(" / ");
                                //解析文件
                                pathText.append(analysisFile(path, file.get("ID").toString())).append(" / ");
                            }
                        }
                    }
                }
                file.put("pathDocName", pathName.toString());
                file.put("pathDocText", pathText.toString());
                //门类编码
                file.put("categoryCode", tenantCategory.get(0).get("CODE").toString());
                //门类id
                file.put("categoryId", tenantCategory.get(0).get("ID").toString());
                //件表表名
                file.put("sub_table_name", tenantCategory.get(0).get("FILE_TABLE_NAME").toString());
                file.remove("SUB_TABLE_NAME");
                file.replaceAll((k, v) -> v == null ? "" : String.valueOf(v));
                elasticsearchApiMapper.updateIndex(fileTable, " ID in (" + file.get("ID") + ") ");
                efileData.add(file);
            }

        } catch (Exception e) {
            e.getMessage();
            log.info("电子件层处理 : " + e.getMessage());
        }
        return efileData;
    }


    /**
     * 解析文件
     *
     * @param url
     * @return
     */
    public String analysisFile(String url, String id) {
        String suffix = url.substring(url.lastIndexOf(".") + 1);
        String text = "";
        try {
            if (suffix.equals("txt")) {
                text = getTextFormTxt(url);
            } else {
                Tika tika = new Tika();
                File file = new File(String.valueOf(url));
                if (file.exists()) {
                    text = tika.parseToString(file);
                }
            }
        } catch (Exception e) {
            log.error("文件识别错误:档案id:(" + id + ");文件地址{};错误信息:{}", url, e);
        } finally {
            return text == null ? " " : text;
        }
    }

    /**
     * 获取文件内容方法，因为如果txt文件是ANSI编码且文件内容过少时，tika自动检测文件编码不正确导致解析内容乱码
     *
     * @param url
     * @return
     */
    // 读取txt文件
    public static String getTextFormTxt(String url) {
        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;
        File file = new File(url);
        byte[] data = null;
        if (!file.exists()) {
            return null;
        }
        String text = "";
        try {
            fis = new FileInputStream(file);
            baos = new ByteArrayOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            data = baos.toByteArray();
            String encoding = get_charset(data);
            text = new String(data, encoding);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return text;
    }

    // 获得txt文件编码方式
    private static String get_charset(byte[] file) throws IOException {
        String charset = "GBK";
        byte[] first3Bytes = new byte[3];
        InputStream bis = null;
        try {
            boolean checked = false;
            bis = new ByteArrayInputStream(file);
            bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "UTF-16LE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
                charset = "UTF-16BE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB
                    && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF-8";
                checked = true;
            }
            bis.reset();
            if (!checked) {
                while ((read = bis.read()) != -1) {
                    if (read >= 0xF0)
                        break;
                    if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的，也算是GBK
                        break;
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
                            // (0x80 - 0xBF),也可能在GB编码内
                            continue;
                        else
                            break;
                    } else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错，但是几率较小
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else
                                break;
                        } else
                            break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                bis.close();
            }
        }
        return charset;
    }


    public String selectConfigByKey(String configKey) {
        String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey)));
        if (cn.yuanqiao.common.utils.StringUtils.isNotEmpty(configValue)) {
            return configValue;
        }

        Map<String, Object> retConfig = elasticsearchApiMapper.selectConfig(configKey, SecurityUtils.getTenantCode());
        if (cn.yuanqiao.common.utils.StringUtils.isEmpty(retConfig)) {
            redisService.setCacheObject(getCacheKey(configKey), retConfig.get("CONFIG_VALUE"));
            return retConfig.get("CONFIG_VALUE").toString();
        }
        return StringUtils.EMPTY;
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return SecurityUtils.getTenantCode() + "_" + CacheConstants.SYS_CONFIG_KEY + configKey;
    }

    /**
     * 查询元数据方案表字段 并进行拼接处理
     *
     * @param
     * @return java.lang.String
     * @author hbWang
     * @date 2023/6/25 11:29
     */
    private String mdataList(String groupId, String type, List<String> fileds, String tenantCode) {
        // type 0 组件 2 电子文件  3  项目 1 组卷 SecurityUtils.getTenantCode()
        List<Map<String, Object>> sourceList = elasticsearchApiMapper.selectMDataListTableDataNew
                (tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                        " and tn.GROUP_ID in ('" + groupId + "') and tn.TYPE = " + type);
        StringBuilder sql = new StringBuilder();
        if (sourceList.size() > 0 && !sourceList.isEmpty()) {
            sourceList.forEach(source -> {
                if ("5".equals(source.get("SHOWTYPE").toString())) {
                    //sql.append(" ( select dict_label from " + tenantCode + "_DICT_DATA ");
                    //sql.append(" where  status = '0' and dict_type = '" + source.get("FIELD_NAME") + "' ");
                    //sql.append(" and dict_value = " + source.get("FIELD_NAME") + " ) AS  ");
                    //sql.append(source.get("FIELD_NAME") + ", ");
                    //直接去数据库拿字典,不使用redis,value中指定了类型
                    List<Map<String, Object>> list = elasticsearchApiMapper.getdictdata(source.get("FIELD_NAME").toString(), tenantCode + "_DICT_DATA");

                    sql.append("(case " + source.get("FIELD_NAME"));
                    if (list.size() == 0) {
                        sql.append(" when '' then '' ");
                    } else {
                        for (int i = 0; i < list.size(); i++) {
                            sql.append(" when '" + list.get(i).get("DICT_VALUE") + "' then '" + list.get(i).get("DICT_LABEL") + "' ");
                        }
                    }

                    sql.append(" else '' end)as " + source.get("FIELD_NAME") + ",");
                } else {
                    sql.append(" f." + source.get("FIELD_NAME") + ",");
                }
            });
            String sqls = sql.toString();
            if (sqls.endsWith(",")) {
                sqls = sql.deleteCharAt(sql.lastIndexOf(",")).toString();
            }
            if (!sourceList.stream().anyMatch(m -> m.get("FIELD_NAME").equals("CREATE_ID"))) {
                sqls = sqls + " ,f.CREATE_ID ";

            }
            return " , " + sqls;
        }
        return "";
    }


    /**
     * 借阅权限
     *
     * @param dataList
     * @param menuId
     * @return
     */
    public List<Map<String, Object>> authority(List<Map<String, Object>> dataList, String menuId) {
        if (ObjectUtils.isEmpty(dataList)) {
            return null;
        }
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        boolean allMatch = false;
        if (roles != null && roles.size() > 0) {
            allMatch = roles.stream().anyMatch(a -> a.getRoleKey().trim().equals("dagly"));
        }
        for (Map<String, Object> data : dataList) {
            //is_borrowing_car   0 不需要借阅 1 需要借阅
            int isBorrowingCar = 1;
            if (allMatch) {
                data.put("is_borrowing_car", "0");
                continue;
            }
            if (data.containsKey("IS_OPENS")) {
                //IS_OPENS  0 不开放  1 开放
                String isOpens = data.get("IS_OPENS").toString();
                if ("开放".equals(isOpens)) {
                    data.put("is_borrowing_car", "0");
                    continue;
                }
            }
            String tableName = data.get("sub_table_name").toString();
            String tablenametype = tableName.substring(tableName.length() - 3, tableName.length() - 2);
            if (isBorrowingCar == 1) {
                if (data.containsKey("CREATE_ID")) {
                    //归档处室
                    String gdcsId = null;
                    if (data.containsKey("GDCS_ID")) {
                        gdcsId = data.get("GDCS_ID") == null ? "" : data.get("GDCS_ID").toString();
                    }
                    StringBuilder sql = new StringBuilder();
                    if ("F".equalsIgnoreCase(tablenametype)) {//档案层
                        sql.append(" FILE_TABLE_NAME = '");
                    } else if ("V".equalsIgnoreCase(tablenametype)) {//案卷层
                        sql.append(" FOLDER_TABLE_NAME = '");
                    } else if ("X".equalsIgnoreCase(tablenametype)) {//项目层
                        sql.append(" ITEM_TABLE_NAME = '");
                    }
                    sql.append(tableName).append("'  and is_del=0");
                    String tenantCode = SecurityUtils.getTenantCode().toUpperCase();
                    //创建人id
                    String createId = data.get("CREATE_ID").toString();
                    String categoryId = elasticsearchApiMapper.selectAppData(tenantCode + Constants.BIG_TABLE_NAME, " ID ", sql.toString());
                    if (roleTree(menuId, createId, categoryId, gdcsId)) {
                        isBorrowingCar = 0;
                    }
                }
            }
            data.put("is_borrowing_car", isBorrowingCar);
        }
        return dataList;
    }

    /**
     * 角色判断
     *
     * @param menuId
     * @param createId
     * @param categoryId
     * @return
     */
    public boolean roleTree(String menuId, String createId, String categoryId, String gdcsId) {
        String tenantCode = SecurityUtils.getTenantCode().toUpperCase();
        boolean b = false;
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        Long dept = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        if (roles != null && roles.size() > 0) {
            for (SysRole role : roles) {
                //查询角色关联档案门类
                StringBuilder sqlStringTr = new StringBuilder();
                //查询角色关联档案门类
                sqlStringTr.append(" id in ( select tree_id from ").append(tenantCode + "_TREESROLE")
                        .append(" where  ROLE_ID = '").append(role.getRoleId()).append("' AND MENU_ID = '").append(menuId).append("' ) and category_id = '")
                        .append(categoryId).append("' ");
                String countCgId = elasticsearchApiMapper.selectAppData(tenantCode + Constants.ABLE_TREES, " COUNT(*) ", sqlStringTr.toString());
                if (!"0".equals(countCgId)) {
                    StringBuilder sqlString = new StringBuilder();
                    String dataScope = role.getDataScope();
                    String userIdNum = "0";
                    if (DataScopeStaticValue.DATA_SCOPE_ALL.equals(dataScope)) {
                        userIdNum = "1";
                    } else if (DataScopeStaticValue.DATA_SCOPE_CUSTOM.equals(dataScope)) {
//                        sqlString.append(" su.dept_id in ( select dept_id from sys_role_dept where ROLE_ID = '")
//                                .append(role.getRoleId()).append("' ) and su.user_id= '").append(createId).append("' ");
//                        userIdNum = elasticsearchApiMapper.selectAppData(" sys_user su ", " COUNT(*) ", sqlString.toString());
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        sqlString.append(" ROLE_ID='").append(role.getRoleId()).append("' and dept_id=  '")
                                .append(gdcsId).append("' ");
                        userIdNum = elasticsearchApiMapper.selectAppData(" sys_role_dept ", " COUNT(*) ", sqlString.toString());
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT.equals(dataScope)) {
//                        sqlString.append(" su.dept_id in ( select dept_id from sys_dept where dept_id = '")
//                                .append(dept).append("' ) and su.user_id=  '").append(createId).append("' ");
//                        userIdNum = elasticsearchApiMapper.selectAppData(" sys_user su ", " COUNT(*) ", sqlString.toString());
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        if (String.valueOf(dept).equals(gdcsId)) {
                            userIdNum = "1";
                        }
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
//                        sqlString.append(" su.dept_id in ( select dept_id from sys_dept where dept_id = '")
//                                .append(dept).append("' or find_in_set( '").append(dept).append("' , ancestors )) and su.user_id=  '")
//                                .append(createId).append("' ");
//                        userIdNum = elasticsearchApiMapper.selectAppData(" sys_user su ", " COUNT(*) ", sqlString.toString());
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        String table = " ( select dept_id from sys_dept where dept_id = '" + dept + "' or find_in_set( '" + dept + "' , ancestors )) ";
                        sqlString.append(" dept_id = '").append(gdcsId).append("' ");
                        userIdNum = elasticsearchApiMapper.selectAppData(table, " COUNT(*) ", sqlString.toString());
                    } else if (DataScopeStaticValue.DATA_SCOPE_SELF.equals(dataScope)) {
                        if (String.valueOf(SecurityUtils.getUserId()).equals(createId)) {
                            userIdNum = "1";
                        }
                    } else if (DataScopeStaticValue.DATA_SCOPE_DEPT_CUSTOM.equals(dataScope)) {
                        if (StringUtils.isBlank(gdcsId)) {
                            continue;
                        }
                        sqlString.append(" ROLE_ID='").append(role.getRoleId()).append("' and dept_id=  '")
                                .append(gdcsId).append("' ");
                        userIdNum = elasticsearchApiMapper.selectAppData(" sys_role_dept  ", " COUNT(*) ", sqlString.toString());
                    }
                    if (!"0".equals(userIdNum)) {
                        b = true;
                    }
                }
            }
        }
        return b;
    }

    /**
     * 查询门类信息
     *
     * @param type
     * @param menuId
     * @return
     */
    public List<Map<String, Object>> queryCategoryIds(String type, String menuId) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        if (roles == null && roles.size() <= 0) {
            return null;
        }
        String collect = roles.stream().map(m -> String.valueOf(m.getRoleId())).collect(Collectors.joining(","));
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        sql.append(" select c.FILE_TABLE_NAME from " + tenantCode + Constants.BIG_TABLE_NAME_TREESROLE);
        sql.append(" tr LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME_TREES);
        sql.append(" t ON t.ID = tr.TREE_ID ");
        sql.append(" LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME);
        sql.append(" c ON t.CATEGORY_ID = c.ID  where c.IS_DEL = 0 and c.GROUP_ID is not null and t.TYPE='a' ");
        sql.append(" and tr.ROLE_ID IN (" + collect + ")");
        sql.append(" and tr.MENU_ID = '" + menuId + "' ");
        if (StringUtils.isNotBlank(type)) {
            sql.append(" and c.TYPE = " + type);
        }
        //查询门类信息
        List<Map<String, Object>> categoryList = elasticsearchApiMapper.selectLeftJoinTableData("FILE_TABLE_NAME ", "", sql.toString());
        return categoryList;
    }

}
